<?php

namespace app\modules\agent\controllers;
use app\models\Agent;
use app\models\AgentLog;
use app\models\AgentAccount;
use app\models\AgentPackage;
use app\models\Card;
use app\models\CardAttr;
use app\models\CardAttrValue;
use app\models\CardBill;
use app\models\CardDispatchForm;
use app\models\CardStatusChange;
use app\models\Isp;
use app\models\jasper\Api;
use app\models\KeyMap;
use app\models\Package;
use app\models\User;
use app\models\UserPackage;
use app\models\UserCardRecharge;
use app\models\OrderRecharge;
use app\models\MoneyChange;
use Exception;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use Yii;
use yii\base\InvalidConfigException;
use yii\data\Pagination;
use yii\db\Expression;
use yii\helpers\Url;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use yii\web\ForbiddenHttpException;

/**
 * 物联网卡管理
 * Class CardController
 * @package app\modules\agent\controllers
 */
class CardController extends BaseController
{
    /**
     * 套餐列表
     * @return string
     */
    public function actionPackageList()
    {
        $query = AgentPackage::find();
        $query->andWhere(['agent_id' => $this->agent->id]);
        $query->orderBy('id DESC');
        $agentPackageList = $query->all();
        return $this->render('package_list', [
            'agentPackageList' => $agentPackageList,
        ]);
    }

    /**
     * 套餐详情
     * @return string
     * @throws NotFoundHttpException
     */
    public function actionPackageView()
    {
        $id = $this->get('id');
        $agentPackage = AgentPackage::findOne(['id' => $id]);
        if (empty($agentPackage) || $agentPackage->agent_id != $this->agent->id) {
            throw new NotFoundHttpException('没有找到套餐。');
        }
        return $this->render('package_view', [
            'agentPackage' => $agentPackage,
        ]);
    }

    /**
     * 保存套餐销售价AJAX接口
     * @return array
     */
    public function actionSaveSalePrice()
    {
        $id = $this->get('id');
        $agentPackage = AgentPackage::findOne(['id' => $id]);
        if (empty($agentPackage) || $agentPackage->agent_id != $this->agent->id) {
            return ['error' => 'SERVER', 'message' => '没有找到套餐。'];
        }
        $salePrice = $this->get('sale_price');
        $packageName = $this->get('name');
        if (empty($salePrice) || $salePrice < $agentPackage->cost_price) {
            return ['error' => 'SERVER', 'message' => '价格错误，不能低于成本价。'];
        }
        if(empty($packageName)){
            return ['error' => 'SERVER', 'message' => '套餐名称不能为空。'];
        }
        $agentPackage->name = $packageName;
        $agentPackage->sale_price = $salePrice;
        $agentPackage->save();
        return [];
    }

    /**
     * 卡列表
     * @return string
     * @throws BadRequestHttpException
     * @throws NotFoundHttpException
     */
    public function actionList()
    {
        $query = Card::find()->alias('card');
        $query->joinWith('isp isp');
        $query->andWhere(['isp.status' => Isp::STATUS_OK]);
        $searchAgentIdList = [];
        if (!empty($this->get('search_agent'))) {
            /** @var Agent $searchAgent */
            $searchAgent = Agent::find()
                ->andWhere(['username' => $this->get('search_agent')])
                ->one();
            if (empty($searchAgent) || !Agent::checkRelation($this->agent->id, $searchAgent->id)) {
                throw new NotFoundHttpException('没有找到代理商【' . $this->get('search_agent') . '】。');
            } else {
                $searchAgentIdList = [$searchAgent->id];
                if ($this->get('search_sub_agent') == 1) { // 包含下级代理商
                    $searchAgentIdList = array_merge($searchAgentIdList, $searchAgent->getSubAidList());
                }
            }
        }
        if (empty($searchAgentIdList)) {
            /** @var Agent $searchAgent */
            $searchAgent = Agent::find()
                ->andWhere(['id' => $this->agent->id])
                ->one();
            $searchAgentIdList = [$searchAgent->id];
                if ($this->get('search_sub_agent') == 1) { // 包含下级代理商
                    $searchAgentIdList = array_merge($searchAgentIdList, $searchAgent->getSubAidList());
                }
        }
        $query->andWhere(['card.agent_id' => $searchAgentIdList]);
        if (!empty($this->get('search_username'))) {
            /** @var User $searchUser */
            $searchUser = User::find()
                ->andWhere(['username' => $this->get('search_username')])
                ->one();
            if (empty($searchUser) || $searchUser->agent_id != $this->agent->id) {
                throw new NotFoundHttpException('没有找到用户【' . $this->get('search_username') . '】。');
            } else {
                $query->andWhere(['uid' => $searchUser->id]);
            }
        }
        $query->andFilterWhere(['card.status' => $this->get('search_status')]);
        //$query->andFilterWhere(['card.iccid' => $this->get('search_iccid')]);
        $query->andFilterWhere(['like', 'card.iccid', $this->get('search_iccid').'%', false]);
        $query->andFilterWhere(['card.msisdn' => $this->get('search_msisdn')]);
        $query->andFilterWhere(['card.package_id' => $this->get('search_package_id')]);
        $searchEndDayAlert = $this->get('search_end_day_alert');
        if (!empty($searchEndDayAlert)) { // 到期提醒的卡
            $query->andWhere(['>', 'card.term_end_time', 0]);
            $query->andWhere(['<=', 'card.term_end_time', time() + $searchEndDayAlert * 86400]);
        }
        $searchOverload = $this->get('search_overload', 0) == 1;
        if ($searchOverload) {
            $query->joinWith('package package');
            $query->andWhere(new Expression('card.data > package.data'));
        }
        $pagination = new Pagination(['totalCount' => $query->count()]);
        $sortName = $this->get('sort_name', 'card.refresh_time');
        $sortOrder = $this->get('sort_order', 'DESC');
        if (!empty($sortName) && !in_array($sortName, ['card.id', 'card.iccid', 'card.msisdn', 'card.refresh_time', 'card.data', 'card.term_end_time'])) {
            throw new BadRequestHttpException('参数错误。');
        }
        if (!empty($sortOrder) && !in_array($sortOrder, ['ASC', 'DESC'])) {
            throw new BadRequestHttpException('参数错误。');
        }
        $query->orderBy([
            $sortName => ['ASC' => SORT_ASC, 'DESC' => SORT_DESC][$sortOrder],
        ]);
        if ($this->get('export') == 'excel') { // 导出Excel文件
            try {
                $excel = new Spreadsheet();
                $sheet = $excel->setActiveSheetIndex(0);
                foreach ([
                             '编号',
                             '代理商',
                             '用户',
                             '套餐',
                             'ICCID',
                             'MSISDN',
                             'IMSI',
                             '状态',
                             '分配时间',
                             '激活时间',
                             '开关机',
                             '数据用量（本月）',
                             '套餐有效期',
                             '套餐结束时间',
                         ] as $index => $title) {
                    $sheet->setCellValue(chr(65 + $index) . '1', $title);
                }
                $sheet->getStyle('A1:Z1')->applyFromArray(['font' => ['bold' => true], 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER]]);
                $r = 2;
                /** @var Card $card */
                foreach ($query->each() as $card) {
                     $sheet->setCellValueExplicitByColumnAndRow(1, $r, $card->id, DataType::TYPE_NUMERIC);
                    $sheet->setCellValueExplicitByColumnAndRow(2, $r, empty($card->agent_id) ? '' : $card->agent->username, DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(3, $r, empty($card->uid) ? '' : $card->user->username, DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(4, $r, empty($card->package_id) ? '' : $card->package->name, DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(5, $r, $card->iccid, DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(6, $r, $card->msisdn, DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(7, $r, $card->imsi, DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(8, $r, KeyMap::getValue('card_status', $card->status), DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(9, $r, Yii::$app->formatter->asDatetime($card->dispatch_time), DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(10, $r, Yii::$app->formatter->asDatetime($card->active_time), DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(11, $r, $card->on_off, DataType::TYPE_NUMERIC);
                    $sheet->setCellValueExplicitByColumnAndRow(12, $r, Yii::$app->formatter->asShortSize($card->data), DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(13, $r, $card->term_length . KeyMap::getValue('card_term_length_unit', $card->term_length_unit), DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(14, $r, Yii::$app->formatter->asDatetime($card->term_end_time), DataType::TYPE_STRING);
                    $r++;
                }
                $sheet->freezePane('A2');
                header('Content-Type: application/vnd.ms-excel');
                header('Content-Disposition: attachment;filename="card_' . date('Y-m-d') . '.xls"');
                header('Cache-Control: max-age=0');
                $excelWriter = IOFactory::createWriter($excel, 'Xls');
                $excelWriter->save('php://output');
            } catch (Exception $e) {
                Yii::error('导出Excel文件时出错：' . $e->getMessage());
                Yii::error($e->getTraceAsString());
                echo $e->getMessage();
            }
            die();
        }
        if ($this->get('export') == 'csv') { // 导出CSV文件
            header('Content-Type: application/vnd.ms-excel;charset=UTF-8');
            header('Content-Disposition: attachment;filename="card_' . date('Y-m-d') . '.csv"');
            header('Cache-Control: max-age=0');
            echo "编号,用户编号,套餐,ICCID,MSISDN,IMSI,状态,分配时间,激活时间,开关机,数据用量（本月）（B）,套餐有效期,套餐结束时间\r\n";
            /** @var Card $card */
            foreach ($query->each() as $card) {
                echo $card->id, ',';
                echo $card->uid, ',';
                echo empty($card->package_id) ? '' : $card->package->name, ',';
                echo $card->iccid, ',';
                echo $card->msisdn, ',';
                echo $card->imsi, ',';
                echo KeyMap::getValue('card_status', $card->status), ',';
                try {
                    echo Yii::$app->formatter->asDatetime($card->dispatch_time), ',';
                } catch (InvalidConfigException $e) {
                    echo ',';
                }
                echo $card->on_off, ',';
                echo $card->data, ',';
                echo $card->term_length, KeyMap::getValue('card_term_length_unit', $card->term_length_unit), ',';
                try {
                    echo Yii::$app->formatter->asDatetime($card->term_end_time);
                } catch (InvalidConfigException $e) {
                }
                echo "\r\n";
            }
            die();
        }
        $query->offset($pagination->offset)->limit($pagination->limit);
        $cardList = $query->all();
        return $this->render('card_list', [
            'agent' => $this->agent->identity,
            'cardList' => $cardList,
            'pagination' => $pagination,
        ]);
    }

    /**
     * 到期提醒卡列表
     * @return string
     * @throws BadRequestHttpException
     * @throws NotFoundHttpException
     */
    public function actionListEndDayAlert()
    {
        return $this->actionList();
    }

    /**
     * 超流量卡列表
     * @return string
     * @throws BadRequestHttpException
     * @throws NotFoundHttpException
     */
    public function actionListOverload()
    {
        return $this->actionList();
    }

    /**
     * 分配用户
     * @return string
     */
    public function actionDispatch()
    {
        $model = new CardDispatchForm();
        $model->setAttributes($this->get());
        $model->source = 'iccid';
        $model->user_type = 'user';
        $model->agent = $this->agent->identity;
        if ($model->load($this->post()) && $model->dispatch()) {
            AgentLog::info($this->agent->id,'DISPATCH', '分配卡', print_r($model->attributes, true));
            Yii::$app->session->addFlash('success', '分配完成。');
            Yii::$app->session->setFlash('redirect', json_encode([
                'url' => Url::to(['/agent/card/list']),
                'txt' => '卡列表'
            ]));
        }
        return $this->render('card_dispatch', [
            'model' => $model,
        ]);
    }
    /**
     * 修改卡类型
     * @return string
     */
    public function actionAgentIsp(){
        $taocan = Yii::$app->request->post("OrderRecharge");
        $agent = $this->agent->id;
        $model = new OrderRecharge();
        if ($model->load($this->post())) {
            $ischeck = OrderRecharge::changeType($taocan['iccid_list'],$agent,$taocan['isp_id']);
            if($ischeck['code'] =='1001'){
                throw new ForbiddenHttpException($ischeck['msg']);
            }
            AgentLog::info($this->agent->id, '卡类型修改完成', print_r($model->attributes, true));
            Yii::$app->session->addFlash('success', '卡类型修改完成。');
            Yii::$app->session->setFlash('redirect', json_encode([
                'url' => Url::to(['/agent/card/list']),
                'txt' => '卡列表'
            ]));
        }
        
        return $this->render('card_agent_isp',[
            'model' => $model,
            'agent' => $agent
        ]);
    }
    /**
     * 刷新卡信息AJAX接口
     * @return array
     */
    public function actionRefresh()
    {
        $id = $this->get('id');
        $card = Card::findOne(['id' => $id]);
        if (empty($card)) {
            return ['error' => 'SERVER', 'message' => '没有找到卡信息。'];
        }
        try {
            $card->newrefreshBasic();
            return [];
        } catch (Exception $e) {
            return ['error' => 'SERVER', 'message' => $e->getMessage()];
        }
    }

    /**
     * 强制设备断开网络使其重新注册AJAX接口
     * @return array
     */
    public function actionRestart()
    {
        $id = $this->get('id');
        $card = Card::findOne(['id' => $id]);
        if (empty($card) || $card->agent_id != $this->agent->id) {
            return ['error' => 'SERVER', 'message' => '没有找到卡信息。'];
        }
        if ($card->api_id == 1) {
            $api = new Api($card->isp->data);
            try {
                $resp = $api->SendCancelLocation($card->iccid);
                return ['resp' => $resp];
            } catch (Exception $e) {
                return ['error' => 'SERVER', 'message' => $e->getMessage()];
            }
        } else {
            return ['error' => 'SERVER', 'message' => '不支持此操作。'];
        }
    }

    /**
     * 设置卡状态AJAX接口
     * @return array
     */
    public function actionSetCardStatus()
    {
        $id = $this->get('id');
        $card = Card::findOne(['id' => $id]);
        if (empty($card) || $card->agent_id != $this->agent->id) {
            return ['error' => 'SERVER', 'message' => '没有找到卡信息。'];
        }
        $status = $this->get('status');
        if (!in_array($status, Card::STATUS_TRANSFORM_MAP[$card->status])) {
            return ['error' => 'SERVER', 'message' => '无法将卡设置为：' . KeyMap::getValue('card_status', $status)];
        }
        try {
            $card->setStatus($status);
            CardStatusChange::info($id, $card->status, $status, 2, 'agent_id=' . $this->agent->id);
            return [];
        } catch (Exception $e) {
            return ['error' => 'SERVER', 'message' => $e->getMessage()];
        }
    }

    /**
     * 卡详情
     * @return string
     * @throws NotFoundHttpException
     */
    public function actionView()
    {
        $id = $this->get('id');
        $card = Card::findOne(['id' => $id]);
        if (empty($card) || $card->agent_id != $this->agent->id) {
            throw new NotFoundHttpException('没有找到卡信息。');
        }
        return $this->render('card_view', [
            'card' => $card,
        ]);
    }
    //获取套餐价格
    public function actionPackageprice()
    {

        $id = $this->get('id');
        $model = AgentPackage::findOne(['id' => $id])->toArray();
        return [
            'code'=>'1',
            'data'=>$model
        ];

    }
    //订购套餐
    // public function actionOrder(){
    //     $model = new UserCardRecharge(); 
    //     $taocan = Yii::$app->request->post("UserCardRecharge");
    //     $agent_id = $this->agent->id;
    //     $card = Card::findOne(['iccid'=>$taocan['iccid']]);
        
    //     $order_sn = date('YmdHis').rand(1000, 9999);
    //     if($taocan){
    //         if(empty($taocan['iccid'])){
    //             throw new NotFoundHttpException('iccid不能为空，请准确填写');
    //         }
    //         if(empty($taocan['term_length'])){
    //             throw new NotFoundHttpException('订购时长不能为空');
    //         }
    //         $agentPackage = AgentPackage::findOne(['agent_id'=>$agent_id,'package_id'=>$card->package_id]);
    //         if(empty($card)){
    //             throw new NotFoundHttpException('没有找到卡信息');
    //         }
    //         if($agent_id != $card->agent_id){
    //             throw new Exception("此卡不属于您,无法操作。");    
                
    //         }
    //         if(empty($card->package_id)){
    //             throw new Exception("此卡尚未充值，无法订购");
    //         }
    //         $accounts = AgentAccount::findOne(['agent_id'=>$agent_id])->getAttribute('iccid');
    //         if($accounts <= 0){
    //             throw new Exception("您的账户余额不足,请及时充值");
                
    //         }
    //         $model->iccid = $taocan['iccid'];
    //         $model->agent_id = $agent_id;
    //         $model->card_id = $card->id;
    //         $model->package_id = $card->package_id;
    //         $model->term_length = $taocan['term_length'];
    //         $model->term_length_unit = $taocan['term_length_unit'];
    //         $model->price = $agentPackage->cost_price;
    //         $model->money = $agentPackage->cost_price * $taocan['term_length'];
    //         $model->trade_type = '2';
    //         $model->trade_no = $order_sn;
    //         $model->status = '3';
    //         $model->create_time = time();
    //         $model->pay_time = time();
    //         $model->update_time = time();
    //         // $model->source = 0;
    //         $model->remark = $taocan['remark'];
    //         $model->save();
    //         //计算账户余额并写入
    //         $account = AgentAccount::findOne(['agent_id'=>$agent_id])->getAttribute('money');
    //         $account_money = $account - $agentPackage->cost_price * $taocan['term_length'];
    //         Yii::$app->db->createCommand()->update('agent_account', ['money' => $account_money], 'agent_id = :agent_id',['agent_id' => $agent_id])->execute(); 
    //         //生成资金变动记录
    //         $moneychange = new MoneyChange();
    //         $moneychange->money_change = "-".$agentPackage->cost_price * $taocan['term_length'];
    //         $moneychange->left_money = $account_money;
    //         $moneychange->recharge_number = $card->iccid;
    //         $moneychange->order_no = $order_sn;
    //         $moneychange->create_time = time();
    //         $moneychange->money_source = 1;
    //         $moneychange->agent_id = $agent_id;
    //         $moneychange->save();
    //         //更新card表内容
    //         $length = $card->term_length + $taocan['term_length'];
    //         if(empty($card->term_end_time)){
    //             $endtime = time() + $taocan['term_length'] * (30*86400);
    //         }else{
    //             $endtime = $card->term_end_time + $taocan['term_length'] * (30*86400);
    //         }
    //         $order_length = $card->order_length + $taocan['term_length'];
    //         $card->updateAttributes(
    //             ['term_length'=>$length,'term_end_time'=>$endtime,'term_length_unit'=>3,'order_length'=>$order_length,'status'=>Card::STATUS_ACTIVATED
    //             ]
    //         );
            

    //     }        
        
    //     if ($model->load($this->post())){
    //         AgentLog::info($this->agent->id, 'ORDER', '订购：' .Yii::$app->request->userIP);
    //         Yii::$app->session->addFlash('success', '订购完成。');
    //         Yii::$app->session->setFlash('redirect', json_encode([
    //             'url' => Url::to(['/agent/card/list']),
    //             'txt' => '卡列表'
    //         ]));
    //     }
        
    //     return $this->render('order',[
    //         'model' => $model
    //     ]);
    // }
    //订购套餐
    // public function actionOrder(){
    //     $taocan = Yii::$app->request->post("OrderRecharge");
    //     $agent_id = $this->agent->id;
    //     $model = new OrderRecharge(); 
    //     $str = str_replace(array("\r\n", "\r", "\n"), "", $taocan['iccid_list']);
    //     $list = strlen($str) / 20;
    //     $iccidList = [];
    //     $iccidList = preg_split('/\s/',$taocan['iccid_list'], -1, PREG_SPLIT_NO_EMPTY);
    //     foreach ($iccidList as $iccid){
    //         //分条写入充值订单
    //         //$card = Card::findOne(['iccid'=>$iccid]);
    //         $card = Card::find()->andWhere(['like','iccid',$iccid])->one();
    //         $agentPackage = AgentPackage::findOne(['agent_id'=>$agent_id,'package_id'=>$card['package_id']]);
    //         $order_sn = date('YmdHis').rand(1000, 9999);
    //         $recharge = new UserCardRecharge();
    //         $recharge->iccid = $iccid;
    //         $recharge->agent_id = $agent_id;
    //         $recharge->card_id = $card['id'];
    //         $recharge->package_id = $card['package_id'];
    //         $recharge->term_length = $taocan['term_length'];
    //         $recharge->term_length_unit = $taocan['term_length_unit'];
    //         $recharge->price = $agentPackage->cost_price;
    //         $recharge->money = $agentPackage->cost_price * $taocan['term_length'];
    //         $recharge->trade_type = '2';
    //         $recharge->trade_no = $order_sn;
    //         $recharge->status = '3';
    //         $recharge->create_time = time();
    //         $recharge->pay_time = time();
    //         $recharge->update_time = time();
    //         $recharge->remark = $taocan['remark'];
    //         $recharge->save();
    //         $id = $recharge->attributes['id'];
    //         $recharges = UserCardRecharge::findOne(['id' => $id]);
    //         $recharges->setPaid();
    //         // //计算账户余额并写入
    //         $account = AgentAccount::findOne(['agent_id'=>$card['agent_id']]);
    //         $account_money = $account->money - $agentPackage->cost_price * $taocan['term_length'];
    //         $account->money = $account_money;
    //         $account->save();
    //         // //生成资金变动记录
    //         $moneychange = new MoneyChange();
    //         $moneychange->money_change = "-".$agentPackage->cost_price * $taocan['term_length'];
    //         $moneychange->left_money = $account_money;
    //         $moneychange->recharge_number = $card['iccid'];
    //         $moneychange->order_no = $order_sn;
    //         $moneychange->create_time = time();
    //         $moneychange->money_source = 1;
    //         $moneychange->agent_id = $agent_id;
    //         $moneychange->save();
    //         //更新充值时长和总时长
    //         $length = $card['term_length'] + $taocan['term_length'];
    //         if(empty($card['term_length'])){
    //             $endtime = time() + $taocan['term_length'] * (30*86400);
    //         }else{
    //             $endtime = $card['term_end_time'] + $taocan['term_length'] * (30*86400);
    //         }
    //         $order_length = $card['order_length'] + $taocan['term_length'];
    //         $card->updateAttributes(
    //             ['term_length'=>$length,'term_end_time'=>$endtime,'term_length_unit'=>3,'order_length'=>$order_length,'status'=>Card::STATUS_ACTIVATED
    //             ]
    //         );
            
            
    //     }
        
    //     if ($model->load($this->post())){
    //         AgentLog::info($this->agent->id, 'ORDER', '订购：' .Yii::$app->request->userIP);
    //         Yii::$app->session->addFlash('success', '订购完成。');
    //         Yii::$app->session->setFlash('redirect', json_encode([
    //             'url' => Url::to(['/agent/card/list']),
    //             'txt' => '卡列表'
    //         ]));
    //     }
        
    //     return $this->render('order',[
    //         'model' => $model,
    //         'agent_id' => $agent_id
    //     ]);
    // }
    /**
     * post curl
     * @param $url
     * @return mixed
     */
    public function postUrl($url,$data_string){
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Content-Length: ' . strlen($data_string)));
        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            print curl_error($ch);
        }
        curl_close($ch);
        return $result;
    }
    /**
     * 回收用户卡AJAX接口
     * @return array
     */
    public function actionRevokeFromUser()
    {
        $id = $this->get('id');
        $card = Card::findOne(['id' => $id]);
        if (empty($card) || $card->agent_id != $this->agent->id) {
            return ['error' => 'SERVER', 'message' => '没有找到卡信息。'];
        }
        if (empty($card->uid)) {
            return ['error' => 'SERVER', 'message' => '此卡没有分配用户。'];
        }
        $card->uid = null;
        $card->save(false);
        return [];
    }

    /**
     * 回收代理商卡AJAX接口
     * @return array
     */
    public function actionRevokeFromAgent()
    {
        $id = $this->get('id');
        $card = Card::findOne(['id' => $id]);
        if (empty($card)) {
            return ['error' => 'SERVER', 'message' => '没有找到卡信息。'];
        }
        if (empty($card->agent_id)) {
            return ['error' => 'SERVER', 'message' => '此卡没有分配给代理商。'];
        }
        if ($card->agent_id == $this->agent->id) {
            return ['error' => 'SERVER', 'message' => '此卡已经属于您了。'];
        }
        // 回收代理商卡相当于将卡分配给上级代理（如果上级代理没有，则直接设置为null）
        $card->agent_id = $card->agent->pid;
        $card->save(false);
        return [];
    }

    /**
     * 账单列表
     * @return string
     * @throws NotFoundHttpException
     */
    public function actionBill()
    {
        $query = CardBill::find()->alias('bill');
        $query->joinWith('card card');
        $searchAgentIdList = [];
        if (!empty($this->get('search_agent'))) {
            /** @var Agent $searchAgent */
            $searchAgent = Agent::find()
                ->andWhere(['username' => $this->get('search_agent')])
                ->one();
            if (empty($searchAgent) || !Agent::checkRelation($this->agent->id, $searchAgent->id)) {
                throw new NotFoundHttpException('没有找到代理商【' . $this->get('search_agent') . '】。');
            } else {
                $searchAgentIdList = [$searchAgent->id];
                if ($this->get('search_sub_agent') == 1) { // 包含下级代理商
                    $searchAgentIdList = array_merge($searchAgentIdList, $searchAgent->getSubAidList());
                }
            }
        }
        if (empty($searchAgentIdList)) {
            /** @var Agent $searchAgent */
            $searchAgent = Agent::find()
                ->andWhere(['id' => $this->agent->id])
                ->one();
            $searchAgentIdList = [$searchAgent->id];
            if ($this->get('search_sub_agent') == 1) { // 包含下级代理商
                $searchAgentIdList = array_merge($searchAgentIdList, $searchAgent->getSubAidList());
            }
        }
        $query->andWhere(['card.agent_id' => $searchAgentIdList]);
        if (!empty($this->get('search_username'))) {
            /** @var User $searchUser */
            $searchUser = User::find()
                ->andWhere(['username' => $this->get('search_username')])
                ->one();
            if (empty($searchUser) || $searchUser->agent_id != $this->agent->id) {
                throw new NotFoundHttpException('没有找到用户【' . $this->get('search_username') . '】。');
            } else {
                $query->andWhere(['uid' => $searchUser->id]);
            }
        }
        $searchMonth = $this->get('search_month');
        if (!empty($searchMonth)) {
            $query->andWhere(['bill.month' => preg_replace('/\D/', '', $searchMonth)]);
        }
        $query->andFilterWhere(['card.package_id' => $this->get('search_package_id')]);
        $searchIccid = $this->get('search_iccid');
        if (!empty($searchIccid)) {
            $query->joinWith('card card')->andWhere(['card.iccid' => $searchIccid]);
        }
        if ($this->get('export') == 'excel') { // 导出Excel文件
            try {
                $excel = new Spreadsheet();
                /** @var CardAttr[] $attrList 卡自定义属性列表 */
                $attrList = empty($searchUser) ? [] : CardAttr::find()->andWhere(['uid' => $searchUser->id])->all();
                /** @var Package[] $packageList 套餐列表 */
                $packageList = [];
                /** @var array $cardAmount 不同套餐计费数量 */
                $cardAmount = [];
                $query->orderBy('id DESC');
                /** @var CardBill $bill */
                foreach ($query->each() as $bill) {
                    if (!isset($packageList[$bill->package_id])) {
                        $packageList[$bill->package_id] = $bill->package;
                        $cardAmount[$bill->package_id] = 0;
                    }
                    $cardAmount[$bill->package_id] += 1;
                }
                $month = $this->get('search_month');
                $sheet = $excel->setActiveSheetIndex(0);
                $sheet->setCellValueExplicitByColumnAndRow(1, 1, '用户名称', DataType::TYPE_STRING);
                $sheet->setCellValueExplicitByColumnAndRow(2, 1, '套餐', DataType::TYPE_STRING);
                $sheet->setCellValueExplicitByColumnAndRow(3, 1, '月份', DataType::TYPE_STRING);
                $sheet->setCellValueExplicitByColumnAndRow(4, 1, '计费数量（张）', DataType::TYPE_STRING);
                $sheet->setCellValueExplicitByColumnAndRow(5, 1, '单价（元）', DataType::TYPE_STRING);
                $sheet->setCellValueExplicitByColumnAndRow(6, 1, '金额（元）', DataType::TYPE_STRING);
                $i = 0;
                foreach ($packageList as $package) {
                    $sheet->setCellValueExplicitByColumnAndRow(1, 2 + $i, $bill->user->username, DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(2, 2 + $i, $package->name, DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(3, 2 + $i, $month, DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(4, 2 + $i, $cardAmount[$package->id], DataType::TYPE_NUMERIC);
                    $userPackage = UserPackage::findOne(['uid' => $bill->user->id, 'package_id' => $package->id]);
                    $sheet->setCellValueExplicitByColumnAndRow(5, 2 + $i, $userPackage->cost_price, DataType::TYPE_NUMERIC);
                    $sheet->setCellValueExplicitByColumnAndRow(6, 2 + $i, $userPackage->cost_price * $cardAmount[$package->id], DataType::TYPE_NUMERIC);
                    $i += 1;
                }
                if (count($packageList) > 1) {
                    $sheet->mergeCellsByColumnAndRow(1, 2, 1, 1 + count($packageList));
                }
                $sheet->getColumnDimension('A')->setWidth(15);
                $sheet->getColumnDimension('B')->setWidth(20);
                $sheet->getColumnDimension('C')->setWidth(10);
                $sheet->getColumnDimension('D')->setWidth(10);
                $sheet->getColumnDimension('E')->setWidth(10);
                $sheet->getColumnDimension('F')->setWidth(10);
                $sheet->getDefaultRowDimension()->setRowHeight(30);
                $sheet->freezePane('A2');
                $sheet->setTitle('总账单');
                foreach ($packageList as $package) {
                    $userPackage = UserPackage::findOne(['uid' => $bill->user->id, 'package_id' => $package->id]);
                    $sheet = $excel->createSheet();
                    $sheet->freezePane('A2');
                    $sheet->setTitle($package->name);
                    $sheet->setCellValueExplicitByColumnAndRow(1, 1, 'ICCID', DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(2, 1, '客户', DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(3, 1, '套餐', DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(4, 1, '费用', DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(5, 1, '流量（B）', DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(6, 1, '短信（条）', DataType::TYPE_STRING);
                    $sheet->setCellValueExplicitByColumnAndRow(7, 1, '语音（分钟）', DataType::TYPE_STRING);
                    $sheet->getColumnDimension('A')->setWidth(25);
                    $sheet->getColumnDimension('B')->setWidth(15);
                    $sheet->getColumnDimension('C')->setWidth(20);
                    $sheet->getColumnDimension('D')->setWidth(10);
                    $sheet->getColumnDimension('E')->setWidth(10);
                    $sheet->getColumnDimension('F')->setWidth(10);
                    $sheet->getColumnDimension('G')->setWidth(10);
                    $c = 8;
                    foreach ($attrList as $attr) {
                        $sheet->setCellValueExplicitByColumnAndRow($c, 1, $attr->name, DataType::TYPE_STRING);
                        $c += 1;
                    }
                    $r = 2;
                    /** @var CardBill $bill */
                    foreach ($query->each() as $bill) {
                        if ($bill->package_id != $package->id) {
                            continue;
                        }
                        $sheet->setCellValueExplicitByColumnAndRow(1, $r, $bill->card->iccid, DataType::TYPE_STRING);
                        $sheet->setCellValueExplicitByColumnAndRow(2, $r, $bill->user->username, DataType::TYPE_STRING);
                        $sheet->setCellValueExplicitByColumnAndRow(3, $r, $package->name, DataType::TYPE_STRING);
                        $sheet->setCellValueExplicitByColumnAndRow(4, $r, $userPackage->cost_price, DataType::TYPE_NUMERIC);
                        $sheet->setCellValueExplicitByColumnAndRow(5, $r, $bill->data, DataType::TYPE_NUMERIC);
                        $sheet->setCellValueExplicitByColumnAndRow(6, $r, $bill->sms, DataType::TYPE_NUMERIC);
                        $sheet->setCellValueExplicitByColumnAndRow(7, $r, $bill->voice, DataType::TYPE_NUMERIC);
                        $c = 8;
                        foreach ($attrList as $attr) {
                            $value = CardAttrValue::findOne(['uid' => $bill->user->id, 'card_id' => $bill->card_id, 'attr_id' => $attr->id]);
                            if (!empty($value)) {
                                $sheet->setCellValueExplicitByColumnAndRow($c, $r, $value->value, DataType::TYPE_STRING);
                            }
                            $c += 1;
                        }
                        $r += 1;
                    }
                }
                header('Content-Type: application/vnd.ms-excel');
                header('Content-Disposition: attachment;filename="card_bill_' . date('Y-m-d') . '.xls"');
                header('Cache-Control: max-age=0');
                $excelWriter = IOFactory::createWriter($excel, 'Xls');
                $excelWriter->save('php://output');
            } catch (Exception $e) {
                Yii::error('导出Excel文件时出错：' . $e->getMessage());
                Yii::error($e->getTraceAsString());
                echo $e->getMessage();
            }
            die();
        }
        $pagination = new Pagination(['totalCount' => $query->count()]);
        $query->orderBy('id DESC');
        $query->offset($pagination->offset)->limit($pagination->limit);
        $billList = $query->all();
        $attrList = empty($searchUser) ? [] : CardAttr::find()->andWhere(['uid' => $searchUser->id])->andWhere(['show_in_list' => 1])->all();

        return $this->render('bill_list', [
            'billList' => $billList,
            'attrList' => $attrList,
            'pagination' => $pagination,
        ]);
    }
}
